﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace GFramework
{
    public static class CompositeEventHelper
    {
        public static void Awake(Leaf leaf)
        {
            IAwake awake = leaf as IAwake;
            if (awake != null)
            {
                awake.Awake();
            }
            RegistUpdate(leaf);
        }

        public static void Awake<T>(Leaf leaf, T obj)
        {
            IAwake<T> awake = leaf as IAwake<T>;
            if (awake != null)
            {
                awake.Awake(obj);
            }
            RegistUpdate(leaf);
        }

        public static void Awake<T1, T2>(Leaf leaf, T1 obj1, T2 obj2)
        {
            IAwake<T1, T2> awake = leaf as IAwake<T1, T2>;
            if (awake != null)
            {
                awake.Awake(obj1, obj2);
            }
            RegistUpdate(leaf);
        }

        public static void Awake<T1, T2, T3>(Leaf leaf, T1 obj1, T2 obj2, T3 obj3)
        {
            IAwake<T1, T2, T3> awake = leaf as IAwake<T1, T2, T3>;
            if (awake != null)
            {
                awake.Awake(obj1, obj2, obj3);
            }
            RegistUpdate(leaf);
        }

        public static void Start(Leaf leaf)
        {
            IStart start = leaf as IStart;
            if (start != null)
            {
                start.Start();
            }
        }

        public static void Shutdown(Leaf leaf)
        {
            IShutdown shutdown = leaf as IShutdown;
            if (shutdown != null)
            {
                shutdown.Shutdown();
            }
            UnRegistUpdate(leaf);
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Update比较特殊，需要先注册进来
        /// </summary>
        //////////////////////////////////////////////////////////////////////////////////////////////////////

        private static readonly GMultiDictionary<Type, IUpdate> s_NeedUpdateDic = new GMultiDictionary<Type, IUpdate>();

        private static void RegistUpdate(Leaf leaf)
        {
            IUpdate update = leaf as IUpdate;
            if(update != null)
            {
                s_NeedUpdateDic.Add(leaf.GetType(), update);
            }
        }

        private static void UnRegistUpdate(Leaf leaf)
        {
            IUpdate update = leaf as IUpdate;
            if (update != null)
            {
                s_NeedUpdateDic.Remove(leaf.GetType(), update);
            }
        }

        public static void Update(float elapseSeconds, float realElapseSeconds)
        {
            foreach(var pair in s_NeedUpdateDic)
            {
                foreach(var range in pair.Value)
                {
                    range?.Update(elapseSeconds, realElapseSeconds);
                }
            }
        }
    }
}
